package com.wufun.baselibrary.download;

import android.annotation.SuppressLint;
import android.os.Handler;
import android.os.Message;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

/**
 * Created by lala on 2017/3/18.
 */

public class CommonDownloadFactory {

    private static CommonDownloadFactory factory;

    private List<DownloadListener> listeners = Collections.synchronizedList(new ArrayList<DownloadListener>());
    private Map<String,CommonDownloadTask> tasks = new ConcurrentHashMap<>(0);
    private ThreadPoolExecutor executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
    @SuppressLint("HandlerLeak")
    private Handler mHandler = new Handler(){
        @Override
        public void handleMessage(Message msg) {
            super.handleMessage(msg);

            synchronized (listeners){
                if(listeners.size()==0)return;
                Iterator<DownloadListener> iterator = listeners.iterator();
                while (iterator.hasNext()){
                    String key = msg.obj.toString();
                    DownloadListener l = iterator.next();
                    if(msg.what == CommonDownloadTask.STATUS_START){
                        try {
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            String gameName = t[1];
                            l.onDownloadStart(url, gameName);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }else if(msg.what == CommonDownloadTask.STATUS_SIZE){
                        try {
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            long size = Long.valueOf(t[1]);
                            l.onDownloadWait(url, size);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }else if(msg.what == CommonDownloadTask.STATUS_ERROR){
//                        iterator.remove();
                        try {
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            String gameName = t[1];
                            l.onDownloadError(url, gameName);
                            removeTask(key);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }else if(msg.what == CommonDownloadTask.STATUS_ZIP_FAIL){//解压失败
//                        iterator.remove();
                        try {
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            String gameName = t[1];
                            l.onDownloadZIPError(url, gameName);
                            removeTask(key);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }else if(msg.what == CommonDownloadTask.STATUS_STOP){
//                        iterator.remove();
                        try {
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            String gameName = t[1];
                            l.onDownloadStop(url, gameName);
                            removeTask(key);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }else if(msg.what == CommonDownloadTask.STATUS_FINISH){
//                        iterator.remove();
                        try {
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            String gameName = t[1];
                            l.onDownloadFinish(url, gameName);
                            removeTask(key);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }

                    }else if(msg.what == CommonDownloadTask.STATUS_PROGRESS){
                        try{
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            int percent = Integer.parseInt(t[2]);
                            String speed = t[1];
                            l.onDownloadProgress(url,percent,speed);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }else if(msg.what == CommonDownloadTask.STATUS_ZIP_PROGRESS){//解压中
                        try{
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            int percent = Integer.parseInt(t[2]);
                            String speed = t[1];
                            l.onDownloadZIPProgress(url,percent,speed);
                        }catch (Exception e){
                            e.printStackTrace();
                        }
                    }else if(msg.what == CommonDownloadTask.STATUS_STSRT_ZIP){//开始解压
                        try {
                            String[] t = msg.obj.toString().split(";");
                            String url = t[0];
                            String gameName = t[1];
                            l.onDownloadStarZIP(url, gameName);
                            removeTask(key);
                        } catch (Exception e) {
                            e.printStackTrace();
                        }
                    }
                }
            }


        }
    };
    private CommonDownloadFactory(){}

    public static CommonDownloadFactory get(){
        if(factory==null)factory = new CommonDownloadFactory();
        return factory;
    }
//    /**
//     * @param tasksList
//     */
//    public void addTaskList(List<Callable<String>> tasksList) {
//        for (Callable<String> t : tasksList) {
//            FutureTask<String> futureTask = new FutureTask<String>(t);
//            executor.execute(t);
//
//            String key = Long.toHexString(System.nanoTime());
//            tasks.put(key, futureTask);
//        }
//    }

    /**
     * @param task
     * @return
     */
    public String addTask(CommonDownloadTask task) {
        if(task==null||task.getUrl()==null||task.getUrl().equals(""))return "";
        String url = task.getUrl();
//        if(tasks.get(task.getUrl())!=null)return url;
        task.setHandler(mHandler);
        Message msg = Message.obtain();
        msg.obj = url+";"+task.getGameName();
        msg.what = CommonDownloadTask.STATUS_START;
        mHandler.sendMessage(msg);
        executor.execute(task);
        synchronized (tasks){
            tasks.put(url, task);
        }

        return url;
    }



    public void removeAllTask() {
        for (String key : tasks.keySet()) {
            executor.remove(tasks.get(key));
            tasks.remove(key);
        }
    }

    /**
     * @param key
     */
    public void removeQueryTask(String key) {
        executor.remove(tasks.get(key));
    }


    /**
     * @param key
     */
    public void removeTask(String key) {
        synchronized (tasks){
            tasks.remove(key);
        }
    }

    public void clearTaskList() {
        tasks.clear();
    }

    public synchronized void stop(){
        try {
            executor.shutdownNow();
            executor.awaitTermination(1L, TimeUnit.MILLISECONDS);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            executor = null;
            tasks.clear();
            tasks = null;
        }
    }

    /**
     * @param key
     */
    public void cancelTask(String key) {
        CommonDownloadTask t = tasks.get(key);
        if(t!=null)t.cancel();
    }

    public boolean isExitTask(String key) {
        CommonDownloadTask t = tasks.get(key);
        if(t!=null)t.cancel();
        return t!=null;
    }

    public void purgeCancelTask() {
        executor.purge();
        executor.getQueue();
    }

    public interface DownloadListener{
        void onDownloadStart(String url, String gameName);
        void onDownloadWait(String url, long size);
        void onDownloadProgress(String url, int progress, String speed);
        void onDownloadFinish(String url, String gameName);
        void onDownloadError(String url, String gameName);
        void onDownloadStarZIP(String url, String gameName);
        void onDownloadZIPProgress(String url, int progress, String speed);
        void onDownloadZIPError(String url, String gameName);
        /** 用户手动暂停*/
        void onDownloadStop(String url, String gameName);
    }

    public void setListener(DownloadListener listener) {
        synchronized(listeners){listeners.add(listener);}
    }

    public void removeListener(DownloadListener listener){
        synchronized (listeners){
            Iterator<DownloadListener> it = listeners.iterator();
            while (it.hasNext()){
                if(listener==it.next()){
                    it.remove();
                }
            }
        }

    }

}
